package cn.biplam.common.tools;

import java.io.Serializable;
import java.lang.reflect.Method;

import cn.biplam.common.wrapper.ErrorMessage;

/**
 * 	用在方法动态调用时存储类名和方法名的对象,可以远程传递
 * @author XiaoRuxing
 * @create上午11:15:37
 * @version 1.0
 */
public class CallMethod implements Serializable{

	private static final long serialVersionUID = 5432158643289000654L;

	/** 方法参数类型 */
	@SuppressWarnings("unchecked")
	private Class[] cParamTypes;

	/** 方法参数值 */
	private Object[] oParams;

	/** 方法执行的返回结果，如果正常执行存放返回值，如果发生异常，存放异常信息 */
	private Object oResult;

	/** 类名或者接口名 */
	private String sClassName;

	/** 方法名 */
	private String sMethodName;

	private Object oMethodObject;
	/**
	 * @param methodName 方法名
	 * @param callClass 装载类对象
	 */
	public CallMethod(String methodName,Object oMethodObject){
		this.sClassName = oMethodObject.getClass().getName();
		this.oMethodObject=oMethodObject;
		this.sMethodName=methodName;
	}

	/**
	 * 构造方法
	 * @param methodName  方法名
	 * @param paramTypes  方法参数列表
	 * @param params      方法值列表
	 * @param callClass   装载类对象
	 */
	@SuppressWarnings("unchecked")
	public CallMethod(Object oMethodObject,String methodName, Class[] paramTypes,
			Object[] params) {
		this.sClassName = oMethodObject.getClass().getName();
		this.oMethodObject=oMethodObject;
		this.sMethodName = methodName;
		this.cParamTypes = paramTypes;
		this.oParams = params;
	}

	/**
	 * 执行对象的方法 
	 * @return 执行结果
	 * @throws ErrorMessage
	 */
	@SuppressWarnings({ "unchecked", "unchecked" })
	public Object invoke() throws ErrorMessage{

		/** 结果对象 */
		Object oResult=null;

		try {
			/** 取出对象各参数 */
			String className = getClassName();
			String methodName = getMethodName();
			Class[] paramTypes = getParamTypes();
			Object[] params = getParams();

			/** 获取类 */
			Class classType=Class.forName(className);

			/** 获取方法 */		
			Method method= classType.getMethod(methodName, paramTypes);

			/** 调用oMethodObject的指定方法，并将值放入result */
			oResult=method.invoke(oMethodObject, params);
		}catch (Exception e) {
			Throwable reason=e.getCause();
			if(reason!=null){
				throw new ErrorMessage(reason,true);
			}else{
				throw new ErrorMessage(e,"CallMethod.invoke failed!");
			}
		}
		return oResult;
	}

	/**
	 * 获取类名
	 * @return
	 */
	public String getClassName() {
		return sClassName;
	}

	/**
	 * 获取方法名
	 * @return
	 */
	public String getMethodName() {
		return sMethodName;
	}

	/**
	 * 获取参数值列表
	 * @return
	 */
	public Object[] getParams() {
		return oParams;
	}

	/**
	 * 获取参数类型列表
	 * @return
	 */
	@SuppressWarnings("unchecked")
	public Class[] getParamTypes() {
		return cParamTypes;
	}

	/**
	 * 获取结果
	 * @return
	 */
	public Object getResult() {
		return oResult;
	}

	/**
	 * 设置类名
	 * @param className 类名
	 */
	public void setClassName(String className) {
		sClassName = className;
	}

	/**
	 * 设置方法名
	 * @param methodName
	 */
	public void setMethodName(String methodName) {
		sMethodName = methodName;
	}

	/**
	 * 设置参数值列表
	 * @param params 参数值
	 */
	public void setParams(Object[] params) {
		oParams = params;
	}

	/**
	 * 设置参数类型列表
	 * @param paramTypes 参数类型
	 */
	@SuppressWarnings("unchecked")
	public void setParamTypes(Class[] paramTypes) {
		cParamTypes = paramTypes;
	}

	/**
	 * 设置结果
	 * @param result
	 */
	public void setResult(Object result) {
		oResult = result;
	}

	/** 
	 * 对象字符串表示，类名、方法名
	 * @return
	 */
	public String toString() {
		return"className=" + sClassName + "，methodName=" + sMethodName;
	}


}
